{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "from PIL import Image \r\n",
    "from IPython.display import display \r\n",
    "import random\r\n",
    "import json"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# Each image is made up a series of traits\r\n",
    "# The weightings for each trait drive the rarity and add up to 100%\r\n",
    "\r\n",
    "background = [\"Blue\", \"Orange\", \"Purple\", \"Red\", \"Yellow\"] \r\n",
    "background_weights = [30, 40, 15, 5, 10]\r\n",
    "\r\n",
    "circle = [\"Blue\", \"Green\", \"Orange\", \"Red\", \"Yellow\"] \r\n",
    "circle_weights = [30, 40, 15, 5, 10]\r\n",
    "\r\n",
    "square = [\"Blue\", \"Green\", \"Orange\", \"Red\", \"Yellow\"] \r\n",
    "square_weights = [30, 40, 15, 5, 10]\r\n",
    "\r\n",
    "# Dictionary variable for each trait. \r\n",
    "# Eech trait corresponds to its file name\r\n",
    "\r\n",
    "background_files = {\r\n",
    "    \"Blue\": \"blue\",\r\n",
    "    \"Orange\": \"orange\",\r\n",
    "    \"Purple\": \"purple\",\r\n",
    "    \"Red\": \"red\",\r\n",
    "    \"Yellow\": \"yellow\",\r\n",
    "}\r\n",
    "\r\n",
    "circle_files = {\r\n",
    "    \"Blue\": \"blue-circle\",\r\n",
    "    \"Green\": \"green-circle\",\r\n",
    "    \"Orange\": \"orange-circle\",\r\n",
    "    \"Red\": \"red-circle\",\r\n",
    "    \"Yellow\": \"yellow-circle\"   \r\n",
    "}\r\n",
    "\r\n",
    "square_files = {\r\n",
    "    \"Blue\": \"blue-square\",\r\n",
    "    \"Green\": \"green-square\",\r\n",
    "    \"Orange\": \"orange-square\",\r\n",
    "    \"Red\": \"red-square\",\r\n",
    "    \"Yellow\": \"yellow-square\"  \r\n",
    "          \r\n",
    "}"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "## Generate Traits\r\n",
    "\r\n",
    "TOTAL_IMAGES = 30 # Number of random unique images we want to generate\r\n",
    "\r\n",
    "all_images = [] \r\n",
    "\r\n",
    "# A recursive function to generate unique image combinations\r\n",
    "def create_new_image():\r\n",
    "    \r\n",
    "    new_image = {} #\r\n",
    "\r\n",
    "    # For each trait category, select a random trait based on the weightings \r\n",
    "    new_image [\"Background\"] = random.choices(background, background_weights)[0]\r\n",
    "    new_image [\"Circle\"] = random.choices(circle, circle_weights)[0]\r\n",
    "    new_image [\"Square\"] = random.choices(square, square_weights)[0]\r\n",
    "    \r\n",
    "    if new_image in all_images:\r\n",
    "        return create_new_image()\r\n",
    "    else:\r\n",
    "        return new_image\r\n",
    "    \r\n",
    "    \r\n",
    "# Generate the unique combinations based on trait weightings\r\n",
    "for i in range(TOTAL_IMAGES): \r\n",
    "    \r\n",
    "    new_trait_image = create_new_image()\r\n",
    "    \r\n",
    "    all_images.append(new_trait_image)\r\n",
    "    \r\n"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# Returns true if all images are unique\r\n",
    "def all_images_unique(all_images):\r\n",
    "    seen = list()\r\n",
    "    return not any(i in seen or seen.append(i) for i in all_images)\r\n",
    "\r\n",
    "print(\"Are all images unique?\", all_images_unique(all_images))"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# Add token Id to each image\r\n",
    "i = 0\r\n",
    "for item in all_images:\r\n",
    "    item[\"tokenId\"] = i\r\n",
    "    i = i + 1"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "print(all_images)"
   ],
   "outputs": [],
   "metadata": {
    "tags": []
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# Get Trait Counts\r\n",
    "\r\n",
    "background_count = {}\r\n",
    "for item in background:\r\n",
    "    background_count[item] = 0\r\n",
    "    \r\n",
    "circle_count = {}\r\n",
    "for item in circle:\r\n",
    "    circle_count[item] = 0\r\n",
    "\r\n",
    "square_count = {}\r\n",
    "for item in square:\r\n",
    "    square_count[item] = 0\r\n",
    "\r\n",
    "for image in all_images:\r\n",
    "    background_count[image[\"Background\"]] += 1\r\n",
    "    circle_count[image[\"Circle\"]] += 1\r\n",
    "    square_count[image[\"Square\"]] += 1\r\n",
    "    \r\n",
    "print(background_count)\r\n",
    "print(circle_count)\r\n",
    "print(square_count)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "#### Generate Metadata for all Traits \r\n",
    "METADATA_FILE_NAME = './metadata/all-traits.json'; \r\n",
    "with open(METADATA_FILE_NAME, 'w') as outfile:\r\n",
    "    json.dump(all_images, outfile, indent=4)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "  \r\n",
    "    \r\n",
    "#### Generate Images    \r\n",
    "for item in all_images:\r\n",
    "\r\n",
    "    im1 = Image.open(f'./trait-layers/backgrounds/{background_files[item[\"Background\"]]}.jpg').convert('RGBA')\r\n",
    "    im2 = Image.open(f'./trait-layers/circles/{circle_files[item[\"Circle\"]]}.png').convert('RGBA')\r\n",
    "    im3 = Image.open(f'./trait-layers/squares/{square_files[item[\"Square\"]]}.png').convert('RGBA')\r\n",
    "\r\n",
    "    #Create each composite\r\n",
    "    com1 = Image.alpha_composite(im1, im2)\r\n",
    "    com2 = Image.alpha_composite(com1, im3)\r\n",
    "\r\n",
    "    #Convert to RGB\r\n",
    "    rgb_im = com2.convert('RGB')\r\n",
    "    file_name = str(item[\"tokenId\"]) + \".png\"\r\n",
    "    rgb_im.save(\"./images/\" + file_name)\r\n",
    "    \r\n",
    "    \r\n",
    "    "
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "#### Generate Metadata for each Image    \r\n",
    "\r\n",
    "f = open('./metadata/all-traits.json',) \r\n",
    "data = json.load(f)\r\n",
    "\r\n",
    "\r\n",
    "IMAGES_BASE_URI = \"ADD_IMAGES_BASE_URI_HERE\"\r\n",
    "PROJECT_NAME = \"ADD_PROJECT_NAME_HERE\"\r\n",
    "\r\n",
    "def getAttribute(key, value):\r\n",
    "    return {\r\n",
    "        \"trait_type\": key,\r\n",
    "        \"value\": value\r\n",
    "    }\r\n",
    "for i in data:\r\n",
    "    token_id = i['tokenId']\r\n",
    "    token = {\r\n",
    "        \"image\": IMAGES_BASE_URI + str(token_id) + '.png',\r\n",
    "        \"tokenId\": token_id,\r\n",
    "        \"name\": PROJECT_NAME + ' ' + str(token_id),\r\n",
    "        \"attributes\": []\r\n",
    "    }\r\n",
    "    token[\"attributes\"].append(getAttribute(\"Background\", i[\"Background\"]))\r\n",
    "    token[\"attributes\"].append(getAttribute(\"Circle\", i[\"Circle\"]))\r\n",
    "    token[\"attributes\"].append(getAttribute(\"Square\", i[\"Square\"]))\r\n",
    "\r\n",
    "    with open('./metadata/' + str(token_id), 'w') as outfile:\r\n",
    "        json.dump(token, outfile, indent=4)\r\n",
    "f.close()"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [],
   "outputs": [],
   "metadata": {}
  }
 ],
 "metadata": {
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3.9.6 64-bit"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.6"
  },
  "interpreter": {
   "hash": "3d65f8beab89bca824669a8319117cabe601d9aca9a71aad8efeb42336828120"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}